#include "VotantesAutomaticos.h"
#include <ctime>
using namespace Accesorios;
using namespace Manejadores;

VotantesAutomaticos::VotantesAutomaticos() {

	this->manejadorDeVotantes = new ManejadorVotante();
	this->log = Log::getInstancia();
}

unsigned int VotantesAutomaticos::generarVotacionesAutomaticas(unsigned int numeroDeVotacionesARealizar) {

	unsigned int votosRealizados = 0;
	ManejadorConteo* manejadorConteo = new ManejadorConteo();
	ManejadorLista* manejadorLista = new ManejadorLista();
	ManejadorEleccion* manejadorEleccion = new ManejadorEleccion();
	vector<Votante*>* votantes = this->manejadorDeVotantes->recuperarVotantes(numeroDeVotacionesARealizar);

	for (unsigned int i = 0; i < votantes->size(); i++) {
		Votante* votante = votantes->at(i);
		vector<Eleccion*>* eleccionesDisponibles = new vector<Eleccion*> ();

		if (votante->getDNI() > 0) {
			vector<Eleccion*>* eleccionesDisponibles = manejadorEleccion->recuperarEleccionesFechaYDistrito(
					Utils::fechaDelDia(), votante->getDistrito()->getNombre());

			for (unsigned int i = 0; i < eleccionesDisponibles->size(); i++) {

				//solo lo dejo votar si no votó en esta eleccion
				bool noVoto = true;
				for (unsigned int w = 0; w < votante->getElecciones()->size(); w++) {
					if (eleccionesDisponibles->at(i)->getFecha() == votante->getElecciones()->at(w)->getFecha()
							&& eleccionesDisponibles->at(i)->getCargo()->getNombre() == votante->getElecciones()->at(w)->getCargo()->getNombre()) {
						noVoto = false;
						break;
					}
				}

				if (noVoto) {

					// recupero todas las listas de la elección
					vector<Lista*>* listasDeLaEleccion = manejadorLista->recuperarListasPorFechaYCargo(
							eleccionesDisponibles->at(i)->getFecha(),
							eleccionesDisponibles->at(i)->getCargo()->getNombre());

					if (listasDeLaEleccion->size() > 0) {

						// generamos un numero aleatorio entre 0 y el tamaño de la lista - 1
						int numeroDeListaAVotar = (rand() % (listasDeLaEleccion->size()));

						// realizamos la votación
						manejadorConteo->registrarVoto(
								Utils::convertirEnteroAString(eleccionesDisponibles->at(i)->getFecha()),
								eleccionesDisponibles->at(i)->getCargo()->getNombre(),
								votante->getDistrito()->getNombre(),
								listasDeLaEleccion->at(numeroDeListaAVotar)->getNombre());

						// le registro al votante el voto
						Eleccion* eleccionVotante = new Eleccion(*eleccionesDisponibles->at(i));
						votante->addEleccion(eleccionVotante);
						this->manejadorDeVotantes->modificacion(votante);

						string descripEleccion = Utils::convertirEnteroAString(eleccionesDisponibles->at(i)->getFecha());
						descripEleccion += eleccionesDisponibles->at(i)->getCargo()->getNombre();
						descripEleccion += votante->getDistrito()->getNombre();

						this->log->escribir(
								"El Votante Automatico ha efectuado un voto para la eleccion " + descripEleccion
										+ "y a la lista" + listasDeLaEleccion->at(numeroDeListaAVotar)->getNombre());

						votosRealizados++;

						for (unsigned i = 0; i < listasDeLaEleccion->size(); i++) {
							delete listasDeLaEleccion->at(i);
						}
						delete listasDeLaEleccion;
					}
				}
			}
		}

		for (unsigned i = 0; i < eleccionesDisponibles->size(); i++) {
			delete eleccionesDisponibles->at(i);
		}
		delete eleccionesDisponibles;
		delete votante;
	}

	delete manejadorConteo;
	delete manejadorEleccion;
	delete manejadorLista;
	delete votantes;

	return (unsigned int) votosRealizados;
}

VotantesAutomaticos::~VotantesAutomaticos() {
	delete manejadorDeVotantes;
}
